package thread.wang_bao_ling.c19;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 使用线程池和wait+notify 优化Reconciliation1。（该优化方式有个致命的缺陷详情查看@1处）
 * 150*10+50*10+50*10=2500
 */
public class Reconciliation2 extends ReconciliationAbstract {

    public Reconciliation2(int count) {
        this.count = count;
    }

    public void DoReconciliation()   {
        // 创建2个线程的线程池
        Executor executor = Executors.newFixedThreadPool(2);
            AtomicInteger atomicInteger = new AtomicInteger(2);
            while (count-- > 0) {
                // 查询未对账订单
                executor.execute(() -> {
                    pos = DataBaseHelper.getPOrders();
                    System.out.println("getPOrders--count="+count);
                    int i=atomicInteger.decrementAndGet();
                    if(i==0) {
                        synchronized (this){
                            System.out.println("notify");
                            notify();
                        }
                    }
                });
                // 查询派送单
                executor.execute(() -> {
                    dos = DataBaseHelper.getDOrders();
                    System.out.println("getDOrders--count="+count);
                    int i=atomicInteger.decrementAndGet();
                    if(i==0) {
                        synchronized (this){
                            System.out.println("notify");
                            notify();
                        }
                    }
                });
                try {
                   // Thread.sleep(3000); //@1 如果主线程休眠3000，那么会先执行notify后执行wait，这样会导致主线程一直阻塞
                    synchronized (this) {
                        System.out.println("wait");
                        wait();
                        atomicInteger.set(2);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 执行对账操作
                Object diff = DataBaseHelper.check(pos, dos);
                // 差异写入差异库
                DataBaseHelper.save(diff);
            }

        //停止线程池，不然main方法不会退出，因为只有所有的非守护线程全部退出，守护线程main才会退出
        ((ExecutorService) executor).shutdown();
    }

}
